﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows;
using Blake.NUI.WPF.Utility;
using Microsoft.Kinect;

namespace KinectGhostHunter
{
    public enum BooStatus
    {
        Invisible,
        Hiding,
        Searching,
        Chasing,
        ChasingClose,
        Dead
    }

    class BooImage : Image
    {
        #region Fields

        BitmapSource booEyes;
        BitmapSource booFace;
        BitmapSource booHide;
        BitmapSource booMad;
        BitmapSource booTasty;
        BitmapSource booTeeth;
        BitmapSource booX;

        #endregion

        #region Properties

        public SkeletonPoint BooPosition { get; set; }
        public double lastUserAngle { get; set; }
        public SkeletonPoint BooVelocity { get; set; }
        #region Status

        /// <summary>
        /// The <see cref="Status" /> dependency property's name.
        /// </summary>
        public const string StatusPropertyName = "Status";

        /// <summary>
        /// Gets or sets the value of the <see cref="Status" />
        /// property. This is a dependency property.
        /// </summary>
        public BooStatus Status
        {
            get
            {
                return (BooStatus)GetValue(StatusProperty);
            }
            set
            {
                SetValue(StatusProperty, value);
            }
        }

        /// <summary>
        /// Identifies the <see cref="Status" /> dependency property.
        /// </summary>
        public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(
            StatusPropertyName,
            typeof(BooStatus),
            typeof(BooImage),
            new UIPropertyMetadata(BooStatus.Invisible, new PropertyChangedCallback(OnStatusPropertyChanged)));

        private static void OnStatusPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var boo = obj as BooImage;
            if (boo == null)
                return;

            var oldStatus = (BooStatus)e.OldValue;
            var newStatus = (BooStatus)e.NewValue;

            boo.UpdateStates(oldStatus, newStatus);
        }

        #endregion

        public float TargetUserPositionOffsetY { get; set; }
        public bool IsBooSwarm { get; set; }

        #endregion

        #region Constructors

        public BooImage()
        {
            LoadBoo();
        }

        #endregion

        #region Private Methods

        private void LoadBoo()
        {
            booEyes = new BitmapImage(new Uri(@"pack://application:,,,/Resources/BooEyes.png"));
            booFace = new BitmapImage(new Uri(@"pack://application:,,,/Resources/BooFace.png"));
            booHide = new BitmapImage(new Uri(@"pack://application:,,,/Resources/BooHide.png"));
            booMad = new BitmapImage(new Uri(@"pack://application:,,,/Resources/BooMad.png"));
            booTasty = new BitmapImage(new Uri(@"pack://application:,,,/Resources/BooTasty.png"));
            booTeeth = new BitmapImage(new Uri(@"pack://application:,,,/Resources/BooTeeth.png"));
            booX = new BitmapImage(new Uri(@"pack://application:,,,/Resources/BooX.png"));
            
            this.Opacity = 0.0;
            Status = BooStatus.Invisible;

            this.Source = null;
        }
        
        private void UpdateStates(BooStatus oldStatus, BooStatus newStatus)
        {
            double newOpacity = 1.0;
            BitmapSource delaySource = null;
            if (newStatus == BooStatus.Hiding)
            {
                this.Source = booHide;
                newOpacity = 0.25;
            }
            else if (newStatus == BooStatus.Searching)
            {
                this.Source = booMad;
            }
            else if (newStatus == BooStatus.Chasing)
            {
                this.Source = booTeeth;
            }
            else if (newStatus == BooStatus.ChasingClose)
            {
                this.Source = booTasty;
            }
            else if (newStatus == BooStatus.Invisible)
            {
                newOpacity = 0.0;
            }
            else if (newStatus == BooStatus.Dead)
            {
                this.Source = booX;
                newOpacity = 1.0;
            }

            var clock = AnimateUtility.AnimateElementDouble(this, FrameworkElement.OpacityProperty, newOpacity, 0, .1);
            if (delaySource != null)
            {
                clock.Completed += (s, e) =>
                    {
                        this.Source = delaySource;
                    };
            }
        }

        #endregion
    }
}
